import JSZip from 'jszip'
import { saveAs } from 'file-saver'
import QRCode from 'qrcode'
import { handleExportExcel } from '@/utils/export'

/**
 * 导出卡密二维码和excel
 * @param {*} passwordList 密码列表
 * @param {*} options 列表字段
 */
export async function exportCardZip(passwordList, options) {
  const {
    passwordProp = passwordProp || 'password',
    denomination = denomination || 'denomination',
    value = value || 'value'
  } = options
  try {
    const res = await createCardZip(passwordList, passwordProp, denomination, value)
    if (res) {
      exportZip(res)
      return Promise.resolve('ok')
    }
  } catch (error) {
    return Promise.reject(error)
  }
}

async function createCardZip(passwordList, passwordProp, denomination, value) {
  const keyList = []
  const ZipFiles = []
  passwordList.map(i => {
    keyList.push(i[passwordProp])
  })
  try {
    const QrCodeRes = await createKeysQrCode(keyList)
    if (QrCodeRes) {
      const excel = handleExportExcel(
        {
          fileName: '充值卡密码',
          sheetData: passwordList,
          sheetHeader: ['优享卡密码', '面额(￥)', '优享值'],
          sheetFilter: [passwordProp, denomination, value]
        },
        false
      )
      ZipFiles.push({
        folderName: 'QrCode',
        files: QrCodeRes,
        needFolder: true
      })

      const ExcelName = excel.name.split('.')
      const files = [{ name: ExcelName[0], file: excel, fileExtendName: '.' + ExcelName[1] }]
      ZipFiles.push({
        files: files,
        needFolder: false
      })
      return Promise.resolve(ZipFiles)
    }
  } catch (error) {
    return Promise.reject(error)
  }
}

/**
 * https://stuk.github.io/jszip/documentation/api_jszip/file_data.html
 * 压缩包文件夹加入文件
 * @param {*} zip zip对象
 * @param {*} folderName 文件夹名
 * @param {*} needFolder 是否需要创建文件夹
 * @param {*} fileList 文件列表
 */
function putFileToZip(zip, folderName, needFolder = false, fileList) {
  if (needFolder) {
    if (!folderName) return new Error('文件夹名不允许为空')

    const folder = zip.folder(folderName)
    fileList.map(item => {
      if (!item.file) throw new Error('文件对象为空')
      folder.file(item.name + item.fileExtendName, item.file)
    })
  } else {
    fileList.map(item => {
      if (!item.file) throw new Error('文件对象为空')
      zip.file(item.name + item.fileExtendName, item.file)
    })
  }
}

export function exportZip(ZipFiles, ZipName = new Date().getTime()) {
  const zip = new JSZip()
  ZipFiles.map(item => {
    putFileToZip(zip, item.folderName || '', item.needFolder, item.files)
  })
  zip.generateAsync({ type: 'blob' }).then(function(content) {
    saveAs(content, `${ZipName}.zip`)
  })
}

/**
 * 生成二维码 file对象
 * @param {stringList} keyList 二维码 Key列表
 */
export async function createKeysQrCode(keyList) {
  try {
    const PromiseMap = []
    keyList.map(i => {
      PromiseMap.push(createQrCode(i))
    })
    const res = await Promise.all(PromiseMap)
    if (res.length) {
      return Promise.resolve(res)
    } else {
      return Promise.reject('生成列表为空，请检查传入参数')
    }
  } catch (error) {
    console.error(error)
  }
}

function createQrCode(text) {
  const opts = {
    margin: 0.5,
    errorCorrectionLevel: 'H'
  }
  return new Promise((resolve, reject) => {
    QRCode.toDataURL(text, opts)
      .then(url => {
        resolve({ name: text, file: base64ToFile(url, text), fileExtendName: '.png' })
      })
      .catch(err => {
        reject(err)
      })
  })
}

const base64ToFile = (base64, fileName) => {
  const arr = base64.split(',')
  const type = arr[0].match(/:(.*?);/)[1]

  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], fileName, { type })
}
